home *** CD-ROM | disk | FTP | other *** search
- /*
- ** MacWT -- a 3d game engine for the Macintosh
- ** © 1995, Bill Hayden and Nikol Software
- **
- ** On the Internet:
- ** bmoc1@aol.com (my personal address)
- ** nikolsw@grove.ufl.edu (my school address)
- ** MacWT anonymous FTP site: ftp.circa.ufl.edu/pub/software/ufmug/mirrors/LocalSW/Hayden/
- ** http://grove.ufl.edu:80/~nikolsw (my WWW page, containing MacWT info)
- **
- ** based on wt, by Chris Laurel (claurel@mr.net)
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-
- #define PIXEL_GUARD_VAL ((Pixel) ~0)
-
- #define PIXEL_CYAN16 ((Pixel16) 0x001F)
- #define PIXEL_CYAN ((Pixel) 0xD2)
-
-
- inline void draw_wall_slice(Pixel *start, Pixel *end, Pixel *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width, int baseshift);
-
- inline void draw_floor_slice(Pixel *start, Pixel *tex,
- fixed x, fixed y, fixed dx, fixed dy,
- short tex_width, short npix);
-
- inline void draw_transparent_slice(Pixel *start, Pixel *end, Pixel *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width,
- int tex_height);
-
-
- inline void draw_wall_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width, int baseshift);
-
- inline void draw_floor_slice16(Pixel16 *start, Pixel16 *tex,
- fixed x, fixed y, fixed dx, fixed dy,
- short tex_width, short npix);
-
- inline void draw_transparent_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width,
- int tex_height);
-
-
-
- /*****************************************************************/
-
-
-
- inline void draw_wall_slice(Pixel *start, Pixel *end, Pixel *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width,
- int baseshift)
- {
- unsigned int utex_y;
-
- utex_y = (unsigned int) tex_y;
-
-
- if (baseshift == 10) // (2^(16-10), or 2^6, or 64 pixels)
- {
- utex_y <<= 10;
- tex_dy <<= 10;
-
- while (start >= end)
- {
- *start = tex_base[utex_y >> 26];
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else if (baseshift == 9) // (2^(16-9), or 2^7, or 128 pixels)
- {
- utex_y <<= 9;
- tex_dy <<= 9;
-
- while (start >= end)
- {
- *start = tex_base[utex_y >> 25];
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else // General (but slower) routine to handle any other power-of-2 texture size
- {
- utex_y <<= baseshift;
- tex_dy <<= baseshift;
- baseshift += 16;
-
- while (start >= end)
- {
- *start = tex_base[utex_y >> baseshift];
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- }
-
-
-
-
- inline void draw_floor_slice(Pixel *start, Pixel *tex,
- fixed x, fixed y, fixed dx, fixed dy,
- short log2_tex_height, short npix)
- {
- register Pixel temp;
-
-
- if (log2_tex_height == 6)
- {
- /* width of 64 == 2^6 */
- y <<= 6;
- dy <<= 6;
-
- do {
- x &= 0x3fffff;
-
- // No need to mask y--it rolls automatically *if* ints are 32 bits.
-
- if (*start == PIXEL_CYAN)
- {
- temp = tex[FIXED_TO_INT((y & 0xfc00000) | x)];
- *start++ = temp;
- }
- else
- *start++;
- x += dx;
- y += dy;
- }
- while (--npix > 0);
- }
- else if (log2_tex_height == 7)
- {
- y <<= 7;
- dy <<= 7;
-
- do {
- x &= 0x7fffff;
-
- if (*start == PIXEL_CYAN)
- {
- temp = tex[FIXED_TO_INT((y & 0x3f800000) | x)];
- *start++ = temp;
- }
- else
- *start++;
- x += dx;
- y += dy;
- }
- while (--npix > 0);
- }
- else // General (but slower) routine to handle any other power-of-2 texture size
- {
- do {
- x &= 0xffffffff >> (16 - log2_tex_height);
- x &= 0x3fffff;
-
- /* No need to mask y--it rolls automatically *if* ints
- ** are 32 bits.
- */
-
- if (*start == PIXEL_CYAN)
- {
- temp = tex[FIXED_TO_INT((y & (((1<<log2_tex_height)-1) <<(log2_tex_height+16))) | x)];
- *start++ = temp;
- }
- else
- *start++;
-
- x += dx;
- y += dy;
- }
- while (--npix > 0);
- }
-
- }
-
-
-
-
- inline void draw_transparent_slice(Pixel *start, Pixel *end, Pixel *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width, int baseshift)
- {
- unsigned int utex_y;
- Pixel p;
-
-
- /* As a speed optimization, tex_y and tex_dy are shifted left by several
- ** bits so that tex_y can overflow correctly without explicit
- ** and-masking. For this to occur correctly, it is necessary to
- ** make utex_y an unsigned quantity. This is probably non-portable,
- ** but should work with most architectures.
- */
- utex_y = (unsigned int) tex_y;
-
-
- if (baseshift == 10)
- {
- utex_y <<= 10;
- tex_dy <<= 10;
-
- while (start >= end)
- {
- p = tex_base[utex_y >> 26];
- if (p != PIXEL_CYAN)
- *start = p;
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else if (baseshift == 9)
- {
- utex_y <<= 9;
- tex_dy <<= 9;
-
- while (start >= end)
- {
- p = tex_base[utex_y >> 25];
- if (p != PIXEL_CYAN)
- *start = p;
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else // General (but slower) routine to handle any other power-of-2 texture size
- {
- utex_y <<= baseshift;
- tex_dy <<= baseshift;
- baseshift += 16;
-
- while (start >= end)
- {
- p = tex_base[utex_y >> baseshift];
- if (p != PIXEL_CYAN)
- *start = p;
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
-
- }
-
-
-
-
- // The following are 16-bit versions of the inline drawing functions.
-
-
- inline void draw_wall_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width,
- int baseshift)
- {
- unsigned int utex_y;
-
- utex_y = (unsigned int) tex_y;
-
-
- if (baseshift == 10) // (2^(16-10), or 2^6, or 64 pixels)
- {
- utex_y <<= 10;
- tex_dy <<= 10;
-
- while (start >= end)
- {
- *start = tex_base[utex_y >> 26];
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else if (baseshift == 9) // (2^(16-9), or 2^7, or 128 pixels)
- {
- utex_y <<= 9;
- tex_dy <<= 9;
-
- while (start >= end)
- {
- *start = tex_base[utex_y >> 25];
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else // General (but slower) routine to handle any other power-of-2 texture size
- {
- utex_y <<= baseshift;
- tex_dy <<= baseshift;
- baseshift += 16;
-
- while (start >= end)
- {
- *start = tex_base[utex_y >> baseshift];
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- }
-
-
-
-
- inline void draw_floor_slice16(Pixel16 *start, Pixel16 *tex,
- fixed x, fixed y, fixed dx, fixed dy,
- short log2_tex_height, short npix)
- {
- register Pixel temp;
-
-
- if (log2_tex_height == 6)
- {
- /* width of 64 == 2^6 */
- y <<= 6;
- dy <<= 6;
-
- do {
- x &= 0x3fffff;
-
- // No need to mask y--it rolls automatically *if* ints are 32 bits.
-
- if (*start == PIXEL_CYAN16)
- {
- temp = tex[FIXED_TO_INT((y & 0xfc00000) | x)];
- *start++ = temp;
- }
- else
- *start++;
- x += dx;
- y += dy;
- }
- while (--npix > 0);
- }
- else if (log2_tex_height == 7)
- {
- y <<= 7;
- dy <<= 7;
-
- do {
- x &= 0x7fffff;
-
- if (*start == PIXEL_CYAN16)
- {
- temp = tex[FIXED_TO_INT((y & 0x3f800000) | x)];
- *start++ = temp;
- }
- else
- *start++;
- x += dx;
- y += dy;
- }
- while (--npix > 0);
- }
- else // General (but slower) routine to handle any other power-of-2 texture size
- {
- do {
- x &= 0xffffffff >> (16 - log2_tex_height);
- x &= 0x3fffff;
-
- /* No need to mask y--it rolls automatically *if* ints
- ** are 32 bits.
- */
-
- if (*start == PIXEL_CYAN16)
- {
- temp = tex[FIXED_TO_INT((y & (((1<<log2_tex_height)-1) <<(log2_tex_height+16))) | x)];
- *start++ = temp;
- }
- else
- *start++;
-
- x += dx;
- y += dy;
- }
- while (--npix > 0);
- }
-
- }
-
-
-
-
- inline void draw_transparent_slice16(Pixel16 *start, Pixel16 *end, Pixel16 *tex_base,
- fixed tex_y, fixed tex_dy, int fb_width, int baseshift)
- {
- unsigned int utex_y;
- Pixel p;
-
-
- /* As a speed optimization, tex_y and tex_dy are shifted left by several
- ** bits so that tex_y can overflow correctly without explicit
- ** and-masking. For this to occur correctly, it is necessary to
- ** make utex_y an unsigned quantity. This is probably non-portable,
- ** but should work with most architectures.
- */
- utex_y = (unsigned int) tex_y;
-
-
- if (baseshift == 10)
- {
- utex_y <<= 10;
- tex_dy <<= 10;
-
- while (start >= end)
- {
- p = tex_base[utex_y >> 26];
- if (p != PIXEL_CYAN16)
- *start = p;
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else if (baseshift == 9)
- {
- utex_y <<= 9;
- tex_dy <<= 9;
-
- while (start >= end)
- {
- p = tex_base[utex_y >> 25];
- if (p != PIXEL_CYAN16)
- *start = p;
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
- else // General (but slower) routine to handle any other power-of-2 texture size
- {
- utex_y <<= baseshift;
- tex_dy <<= baseshift;
- baseshift += 16;
-
- while (start >= end)
- {
- p = tex_base[utex_y >> baseshift];
- if (p != PIXEL_CYAN16)
- *start = p;
- utex_y += tex_dy;
- start -= fb_width;
- }
- }
-
- }
-